/*
 * Copyright (c) 2012 Sean Connelly
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var assert = require('../assert.js').init();
var x64 = require('../../src/js/x64.js');

function ins_test(t, f, pars, val)
{
		var x = x64.create();
		var sz = x[f].size();
		var res = x[f].call.apply(x[f], pars).dumpList();
		//console.log(sz, res);
		// test that the assembled bytes match, and the length matches the size() result
		assert.that(t, res === 'byteList{' + val + '}' && sz == (val.length + 1) / 3);
}

exports.run = function(root_dir, test_dir, test_name) {

		var RAX = 0, RCX = 1, RDX = 2, RBX = 3, RSP = 4, RBP = 5, RSI = 6, RDI = 7;
		var R8 = 8, R9 = 9, R10 = 10, R11 = 11, R12 = 12, R13 = 13, R14 = 14, R15 = 15;
		var EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7;

		ins_test('mov rax, rbx',             'mov_r64_r64',    [RAX, RBX], '48 89 d8'            );
		ins_test('mov r8, rcx',              'mov_r64_r64',    [R8, RCX],  '49 89 c8'            );
		ins_test('nop',                      'nop',            [],         '90'                  );
		ins_test('mov QWORD PTR [r10], rsp', 'mov_Qm64_r64',   [R10, RSP], '49 89 22'            );
		ins_test('test r8, r9',              'test_r64_r64',   [R8, R9],   '4d 85 c8'            );
		ins_test('xchg ebx, eax',            'xchg_r32_eax',   [EBX],      '93'                  );
		ins_test('int 45',                   'int_imm8',       [45],       'cd 2d'               );
		ins_test('mov DWORD PTR [esi], 10',  'mov_Dm32_imm32', [ESI, 10],  '67 c7 06 0a 00 00 00');
		ins_test('int3',                     'int3',           [],         'cc'                  );

		return assert.result();
	};
